--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Commit 82c20196e7e98f49e181a121d8910820977e41ab
Parents : 683b3f3
Author : Ivan <ivan@quad4.io>
Signature : Invalid signer <e46112d44649266d71fe2193e00a4710>, author is <ivan@quad4.io>
Date : 2026-07-13T10:53:18-05:00
chore: update security measures by excluding vendor paths from RSM inventory and adding verification steps in CI
Changes
5 files changed, 44 insertions(+), 11 deletions(-)
Diff
diff --git a/.github/actions/setup-dev-environment/action.yml b/.github/actions/setup-dev-environment/action.yml
index 25533621..69ac8033 100644
--- a/.github/actions/setup-dev-environment/action.yml
+++ b/.github/actions/setup-dev-environment/action.yml
@@ -32,6 +32,26 @@ inputs:
runs:
using: composite
steps:
+ # Verify before dependency installs that may rewrite tracked files.
+ - name: Ensure rnid for tree verify
+ if: inputs.skip_tree_verify != 'true'
+ shell: bash
+ run: |
+ set -euo pipefail
+ if command -v rnid >/dev/null 2>&1; then
+ exit 0
+ fi
+ python3 -m pip install --user 'rns>=1.3.8'
+ echo "$HOME/.local/bin" >> "$GITHUB_PATH"
+
+ - name: Verify tree RSM
+ if: inputs.skip_tree_verify != 'true'
+ shell: bash
+ env:
+ RNS_REQUIRED_SIGNER: e46112d44649266d71fe2193e00a4710
+ RNS_INVENTORY_OUT: ${{ runner.temp }}/meshchatx-tree-inventory.txt
+ run: sh scripts/ci/verify-tree-rsm.sh
+
- name: Set up Python and UV
uses: ./.github/actions/setup-python-uv
with:
@@ -52,11 +72,3 @@ runs:
if: inputs.install-task == 'true'
shell: bash
run: sh scripts/ci/setup-task.sh "${{ inputs.task-version }}"
-
- - name: Verify tree RSM
- if: inputs.skip_tree_verify != 'true'
- shell: bash
- env:
- RNS_REQUIRED_SIGNER: e46112d44649266d71fe2193e00a4710
- RNS_INVENTORY_OUT: ${{ runner.temp }}/meshchatx-tree-inventory.txt
- run: sh scripts/ci/verify-tree-rsm.sh
diff --git a/SECURITY.md b/SECURITY.md
index d6ce0cb1..6e56cecd 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -34,7 +34,7 @@ Official release binaries and packages are built in **automation on GitHub**, no
### Source tree integrity (`.rsm`)
-The repository root includes a signed rnid message file, `meshchatx.rsm`. It embeds a SHA-256 inventory of every git-tracked file (except itself). CI verifies the signature against the required signer identity `e46112d44649266d71fe2193e00a4710`, then re-hashes file bytes. Jobs also recheck the inventory at the end so a compromised runner cannot silently add or modify tracked files.
+The repository root includes a signed rnid message file, `meshchatx.rsm`. It embeds a SHA-256 inventory of git-tracked files except itself and paths under any `vendor/` tree. CI verifies the signature against the required signer identity `e46112d44649266d71fe2193e00a4710`, then re-hashes file bytes. Jobs also recheck the inventory at the end so a compromised runner cannot silently add or modify tracked files.
Verify locally:
diff --git a/meshchatx.rsm b/meshchatx.rsm
index 26b070b4..934deda0 100644
Binary files a/meshchatx.rsm and b/meshchatx.rsm differ
diff --git a/scripts/ci/tree-manifest.sh b/scripts/ci/tree-manifest.sh
index 2cfe679e..395c53b4 100755
--- a/scripts/ci/tree-manifest.sh
+++ b/scripts/ci/tree-manifest.sh
@@ -6,6 +6,8 @@
# <sha256-hex> <path>
#
# meshchatx.rsm is excluded from the inventory (avoids a self-hash cycle).
+# Paths under any vendor/ directory are excluded (vendored trees are not
+# first-party inventory).
#
# Paths are listed via newline-delimited git ls-files (POSIX sh / dash safe).
# Do not use read -d or sort -z (bash/GNU-only).
@@ -22,6 +24,18 @@ cd "$ROOT"
MANIFEST_HEADER="# meshchatx tree manifest v1"
EXCLUDE_RSM="meshchatx.rsm"
+# True when path is the root RSM or lives under a vendor directory.
+is_excluded_path() {
+ f="$1"
+ [ "$f" = "$EXCLUDE_RSM" ] && return 0
+ case "$f" in
+ vendor | vendor/* | */vendor | */vendor/*)
+ return 0
+ ;;
+ esac
+ return 1
+}
+
file_sha256_stream() {
if command -v sha256sum >/dev/null 2>&1; then
sha256sum | awk '{print $1}'
@@ -52,7 +66,9 @@ generate() {
printf '%s\n' "$MANIFEST_HEADER"
tracked_paths | while IFS= read -r f; do
[ -n "$f" ] || continue
- [ "$f" = "$EXCLUDE_RSM" ] && continue
+ if is_excluded_path "$f"; then
+ continue
+ fi
if ! git cat-file -e ":$f" 2>/dev/null; then
continue
fi
@@ -117,7 +133,9 @@ verify() {
: >"$tmp_tracked"
tracked_paths | while IFS= read -r f; do
[ -n "$f" ] || continue
- [ "$f" = "$EXCLUDE_RSM" ] && continue
+ if is_excluded_path "$f"; then
+ continue
+ fi
[ -f "$f" ] || continue
[ -L "$f" ] && continue
printf '%s\n' "$f"
diff --git a/scripts/ci/verify-workspace-clean.sh b/scripts/ci/verify-workspace-clean.sh
index 4a532c71..73e80254 100755
--- a/scripts/ci/verify-workspace-clean.sh
+++ b/scripts/ci/verify-workspace-clean.sh
@@ -34,6 +34,9 @@ is_allowed() {
esac
done
case "$p" in
+ vendor | vendor/* | */vendor | */vendor/*)
+ return 0
+ ;;
*.log | *.tmp | *.swp | *.egg-info | *.pyc)
return 0
;;
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────